#!/usr/bin/perl
#
# $Id$
#
# author: ron dilley
#
# desc: this perl script generates statistics about password dictionaries
#
# Copyright (C) 2009  Ron A. Dilley
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ron.dilley@uberadmin.com
#
############################################################################

#
# modules
#
use Getopt::Std;

#
# pragmas
#
use strict;

#
# set environment
#
$ENV{PATH} = "/usr/bin:/bin:/usr/sbin:/sbin:/usr/ucb";

#
# turn on autoflush
#
select STDERR; $| = 1;
select STDOUT; $| = 1;

#
# defines
#
$::TRUE = 1;
$::FALSE = 0;
$::FAILED = -1;

$::VERSION = '$Id$';
$::PROGNAME = "getStats.pl";

%::Config = ();
$::Config{'debug'} = $::FALSE;
$::Config{'maxptlen'} = 14;

#
# main routine
#
if ( &main() != $::TRUE ) {
  exit( 1 );
}

exit( 0 );

############################################################################
#
# sub-routines
#

#
# main routine
#
sub main {
  my $arg;

  #
  # display script banner
  #
  &show_banner();

  #
  # parse command-line
  #
  &parse_command_line();

  # process args that are left
  while( $arg = shift( @::ARGV ) ) {
    processDictFile( $arg );
  }

  &printStats();

  # done
  return $::TRUE;
}

#
# display banner info
#
sub show_banner {
  print stderr "$::PROGNAME v$::VERSION\n";
  print stderr "By: Ron Dilley\n";
  print stderr "\n";
  print stderr "$::PROGNAME comes with ABSOLUTELY NO WARRANTY.\n";
  print stderr "This is free software, and you are welcome\n";
  print stderr "to redistribute it under certain conditions;\n";
  print stderr "See the GNU General Public License for details.\n";
  print stderr "\n";

  return $::TRUE;
}

#
# display help info
#
sub show_help {
  print stderr "Syntax:\n";
  print stderr "\n";
  print stderr "$::PROGNAME [options] {file} [{file} ...]\n";
  print stderr "\n";
  print stderr "-d {0-9}   Display debug information during program run\n";
  print stderr "\n";

  return $::TRUE;
}

#
# parse command-line arguments
#
sub parse_command_line {
  no strict 'vars';

  if ( getopts( 'd:' ) == $::FALSE ) {
    &show_help();
    return $::FAILED;
  }
  if ( defined $opt_d ) {
    if ( $opt_d > 0 ) {
      # set debug mode
      $::Config{'debug'} = $opt_d;
    }
  }

  return $::TRUE;
}

#
# process and compare data from pot files
#
sub processDictFile {
  my ( $fname ) = @_;
  my $line;
  my $pt;
  my $i;
  my $ptLen;
  my @ptTok;

  if ( ! defined open( INFILE, $fname ) ) {
    print stderr "ERR - Unable to open file [$fname]\n";
    return $::FAILED;
  }

  while( $line = <INFILE> ) {
    chomp( $line );
    if ( $line =~ m/^(\$NT\$.{32,32})\:(.*)$/ ) {
      $pt = $2;
    }

    $ptLen = length( $pt );
    @ptTok = split( //, $pt );
    for( $i = 0; $i < $ptLen; $i++ ) {
      if ( exists  $::stats[$ptLen]->[$i]->{$ptTok[$i]} ) {
	$::stats[$ptLen]->[$i]->{$ptTok[$i]}++;
      } else {
	$::stats[$ptLen]->[$i]->{$ptTok[$i]} = 1;
      }
    }
  }

  close( INFILE );

  return $::TRUE;
}

#
# print stats
#
sub printStats {
  my $ptLen;
  my $curPos;
  my $key;
  my %tmpHash;
  my @tmpLenArray;
  my @tmpPosArray;

  for( $ptLen = 1; $ptLen < $::Config{'maxptlen'}; $ptLen++ ) {
    if ( scalar( $::stats[$ptLen] > 0 ) ) {
      print "LENGTH:$ptLen\n";
      print "TOKENS:";
      for ( $curPos = 0; $curPos < $ptLen; $curPos++ ) {
	@tmpLenArray = $::stats[$ptLen];
	%tmpHash = $tmpLenArray[$curPos];
	#foreach ( $key = sort { $tmpHash{$b} <=> $tmpHash{$a} } keys( %tmpHash ) ) {
	foreach $key ( keys( %tmpHash ) ) {
	  print "$key\n";
	}

      }
    }
  }
}
